// FRAOZO - 3b
// Contains the main function, along with testSearch and
// testMatches as dictated in spec.

#include <iostream>
#include <string>
#include "grid.h"
#include "dictionary.h"

#define MINLENGTH 5

using namespace std;

void normalizeIdx(const grid &myGrid, int &newRow, int &newCol)
//Aviod out-of-range indexes
//If passed a row value of 30, it will return a row value of 0
// (ie first row)
{
   int totRows=myGrid.getRows();
   int totCols=myGrid.getCols();
   
   if (newRow<0)
      newRow+=totRows;;
   if (newCol<0)
      newCol+=totCols;

   if (newRow>=totRows)
      newRow-=totRows;
   if (newCol>=totCols)
      newCol-=totCols;
}

string buildString(const grid &myGrid, int row, int col, int hor, int ver, int length)
//Build a string of length length, starting from (row, col) and
// in the direction given by ver and hor
{
   string targetString;
   int currentRow=row;
   int currentCol=col;
   normalizeIdx(myGrid, currentRow, currentCol);

   //For each letter from the start point...
   for (int idx=0; idx<length; idx++)
   {
      targetString += myGrid.indexGrid(currentRow, currentCol);
      currentRow += hor;
      currentCol += ver;
      normalizeIdx(myGrid, currentRow, currentCol);
   }

   return targetString;
} // end buildString

void findMatches (const grid &myGrid, const dictionary &myDict)
//Iterates through each letter in the grid and builds a string
//from the current position.  If the dictionary binarySearch member 
// returns true, pass another string of length+1 to binarySearch until
// it returns false
{
   int minLength=MINLENGTH;

   //iterate through each start point
   for (int row=0; row<myGrid.getRows(); row++)

      for (int col=0; col<myGrid.getCols(); col++)

	 //for each horizontal direction
	 for (int hor=-1; hor<=1; hor++)

	    //For each vertical direction
	    for (int ver=-1; ver<=1; ver++)
	    {
	       bool keepSearching=true;

	       //Generate a target string to lookup in dictionary,
	       //until no matches are found
	       for (int length=minLength; keepSearching; length++)
	       {
		  string target=buildString(myGrid, row, col, hor, ver, length);
		  int match = -1;
		  keepSearching = myDict.binarySearch(match, 0, myDict.getSize()-1, target);

		  //binarySearch case 1 : Exact match is found
		  if (match != -1)
		     cout << target << endl;
	       }

	    }

} // end findMatches

string readKeyboard ()
//Reads the grid file name from the keyboard.
//For simplicity, we place in the possible inputxx
//files in the CWD.
{
   string fileName;
   cout << "Which grid file do you want to open?" << endl;
   cin >> fileName;
   return fileName;
}

void testSearch ()
//Sets up the program to look for matches
//by reading in the contents of the inputxx
//file, and the dictionary file
{
   //Instantiate and load the grid with the input file
   grid myGrid;
   string gridFileName = readKeyboard();
   myGrid.readInputFile(gridFileName);

   //Instantiate and load the dictionary with the input file
   dictionary myDict;
   string dictFileName = "dictionary";
   myDict.readInputFile(dictFileName);
   myDict.quickSort(0, myDict.getSize()-1);

   //Find word matches and print them
   findMatches(myGrid, myDict);

} //end testSearch

int main (int argc, char* argv[]) 
{
   try
   {
      testSearch();
   }
   catch (baseException &err)
   {
      cerr << "Caught exception : " << err.what() << endl;
   }
   return 0;
}
